﻿using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;

namespace LxBasic
{
    public struct Vector2d
    {
        public Vector2d(double x, double y)
        {
            this.X = x;
            this.Y = y;
        }
        public double X;
        public double Y;
        public static Vector2d Zero => new Vector2d(0, 0);
        public static Vector2d UnitX => new Vector2d(1, 0);
        public static Vector2d UnitY => new Vector2d(0, 1);
        public double this[int index]
        {
            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            get
            {
                switch (index)
                {
                    case 0: return X;
                    case 1: return Y;
                    default: throw new IndexOutOfRangeException();
                }
            }
        }
        public void Negate()
        {
            X = -X;
            Y = -Y;
        }
        public void Normalize()
        {
            double l = Length();
            X /= l;
            Y /= l;
        }
        public double LengthSquared() => X * X + Y * Y;

        public double Length() => Math.Sqrt(LengthSquared());
        public bool Equals(Vector3d other)
        {
            return X == other.X && Y == other.Y;
        }
        public override bool Equals([NotNullWhen(true)] object? obj)
        {
            return obj is Vector3d v ? Equals(v) : false;
        }
        public override int GetHashCode()
        {
            return (X.GetHashCode() * 397) ^ Y.GetHashCode();
        }
        public override string ToString()
        {
            return string.Format($"[{X},{Y}]");
        }
        public static bool TryParse(string inputString, out Vector2d result)
        {
            string t3 = inputString.Replace("，", ",");
            t3 = t3.Trim();
            if (t3.StartsWith('[') && t3.EndsWith(']'))
            {
                t3 = t3.Substring(1, t3.Length - 2);
            }
            string[] s3 = t3.Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
            result = new Vector2d();
            return s3.Length == 2
                && double.TryParse(s3[0], out result.X) && double.TryParse(s3[1], out result.Y);
        }
        public static Vector2d Parse(string inputString)
        {
            if (TryParse(inputString, out Vector2d result))
            {
                return result;
            }
            else
            {
                throw new Exception($"转换Vector3d出错 - {inputString}");
            }
        }
        public static bool operator ==(Vector2d a, Vector2d b)
        {
            return a.Equals(b);
        }
        public static bool operator !=(Vector2d a, Vector2d b)
        {
            return !a.Equals(b);
        }
        public static Vector2d operator +(Vector2d a, Vector2d b)
        {
            return new Vector2d(a.X + b.X, a.Y + b.Y);
        }
        public static Vector2d operator -(Vector2d a, Vector2d b)
        {
            return new Vector2d(a.X - b.X, a.Y - b.Y);
        }
        public static Vector2d operator -(Vector2d a)
        {
            return new Vector2d(-a.X, -a.Y);
        }
        public static Vector2d operator *(double d, Vector2d v)
        {
            return new Vector2d(v.X * d, v.Y * d);
        }
        public static Vector2d operator *(Vector2d v, double d)
        {
            return new Vector2d(v.X * d, v.Y * d);
        }
        public static double DotProduct(in Vector2d a, in Vector2d b)
        {
            return a.X * b.X + a.Y * b.Y;
        }
    }
}
